package priv.happy.mealpickpro.controller;

import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.mail.MailProperties;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import priv.happy.mealpickpro.domain.UserMeal;
import priv.happy.mealpickpro.dto.CaptchaDTO;
import priv.happy.mealpickpro.dto.UserDTO;
import priv.happy.mealpickpro.emum.SystemStatusCode;
import priv.happy.mealpickpro.service.AuthenticationService;
import priv.happy.mealpickpro.service.UserMealService;
import priv.happy.mealpickpro.util.CaptchaUtil;
import priv.happy.mealpickpro.util.EmailUtil;
import priv.happy.mealpickpro.vo.ApiResponse;
import priv.happy.mealpickpro.vo.UserVO;

import java.time.Duration;

/**
 * @Author: HAPPY
 * @Project_name: MealPickpro
 * @Package_name: priv.happy.mealpickpro.controller
 * @Date: 2023/7/2 11:30
 * @Description: 认证控制器
 */
@RequestMapping("/api/v2")
@RestController
public class AuthenticationController {
    @Autowired
    StringRedisTemplate stringRedisTemplate;
    @Autowired
    UserMealService userMealService;
    @Autowired
    EmailUtil emailUtil;

    @Autowired
    MailProperties mailProperties;

    @Autowired
    AuthenticationService authenticationService;

    /**
     * 登录接口
     *
     * @param user 登录用户信息
     * @return 返回的data是登录后的用户信息，含token
     */
    @ApiOperation("登录接口")
    @PostMapping("/login")
    public ApiResponse<UserVO> login(@RequestBody UserMeal user) {
        ApiResponse<UserVO> apiResponse = new ApiResponse<>();
        UserVO userVO = null;
        // 判空
        if (user == null || user.getEmail() == null || user.getPassword() == null) {
            apiResponse.setSuccess(false).setCode(SystemStatusCode.UNAUTHORIZED.getCode()).setMessage("账号或密码错误");
        } else {
            userVO = authenticationService.login(user);
            // 登录结果判断
            if (userVO != null && userVO.getUserMeal() != null && userVO.getUserMeal().getId() != null) {
                apiResponse.setData(userVO).setCode(SystemStatusCode.SUCCESS.getCode()).setMessage("登录成功").setSuccess(true);
            } else {
                apiResponse.setSuccess(false).setCode(SystemStatusCode.UNAUTHORIZED.getCode()).setMessage("账号或密码错误");
            }
        }

        return apiResponse;
    }

    /**
     * 获取验证码接口
     *
     * @return 返回发送结果
     */
    @ApiOperation("获取注册验证码")
    @PostMapping("/register/captcha")
    public ApiResponse<String> getCaptcha(@RequestBody CaptchaDTO captchaDTO) {
        ApiResponse<String> apiResponse = new ApiResponse<>();
        if (captchaDTO.getEmail() == null) {
            apiResponse.setSuccess(false).setMessage("请输入邮箱！").setCode(500);
        } else {
            // 注册逻辑
            if ("注册".equals(captchaDTO.getUse())) {
                if (!authenticationService.isRegistered(captchaDTO.getEmail())) {
                    // 发送验证码
                    String captcha = CaptchaUtil.generateRandomCode(6);
                    // 新建线程发送验证码
                    new Thread(() -> emailUtil.sendEmail(captchaDTO.getEmail(), "【餐选】注册验证码", "您的注册验证码是: " + captcha + "，有效期五分钟。")).start();

                    // 将验证码放入redis缓存，有效期5分钟
                    stringRedisTemplate.opsForValue().set("mealpickpro:captcha:register:" + captchaDTO.getEmail(), captcha, Duration.ofSeconds(60 * 5));
                    apiResponse.setCode(200).setMessage("验证码发送成功！").setSuccess(true);
                } else {
                    apiResponse.setCode(SystemStatusCode.UNAUTHORIZED.getCode()).setSuccess(false).setMessage("该邮箱已被注册");
                }
            } else {
                // 重置密码逻辑
                if (authenticationService.isRegistered(captchaDTO.getEmail())) {
                    // 发送验证码
                    String captcha = CaptchaUtil.generateRandomCode(6);
                    // 新建线程发送验证码
                    new Thread(() -> emailUtil.sendEmail(captchaDTO.getEmail(), "【餐选】重置密码验证", "您的重置密码验证码是: " + captcha + "，有效期五分钟。")).start();
                    // 将验证码放入redis缓存，有效期5分钟
                    stringRedisTemplate.opsForValue().set("mealpickpro:captcha:reset:" + captchaDTO.getEmail(), captcha, Duration.ofSeconds(60 * 5));
                    apiResponse.setCode(200).setMessage("验证码发送成功！").setSuccess(true);
                } else {
                    apiResponse.setCode(SystemStatusCode.UNAUTHORIZED.getCode()).setSuccess(false).setMessage("该邮箱尚未注册");
                }
            }

        }

        return apiResponse;
    }

    /**
     * 注册接口
     *
     * @param user 注册用户信息
     * @return 返回注册结果
     */
    @ApiOperation("注册接口")
    @PostMapping("/register")
    public ApiResponse<String> register(@RequestBody UserDTO user) {
        ApiResponse<String> apiResponse = new ApiResponse<>();
        switch (authenticationService.register(user)) {
            case 0:
                apiResponse.setCode(SystemStatusCode.SUCCESS.getCode())
                        .setMessage("注册成功").setSuccess(true);
                break;
            case 1:
                apiResponse.setCode(SystemStatusCode.BAD_REQUEST.getCode())
                        .setMessage("该邮箱已被使用").setSuccess(false);
                break;
            case 2:
                apiResponse.setCode(SystemStatusCode.BAD_REQUEST.getCode())
                        .setMessage("请输入完整信息").setSuccess(false);
            case 3:
                apiResponse.setCode(SystemStatusCode.BAD_REQUEST.getCode())
                        .setMessage("验证码错误").setSuccess(false);
                break;
            default:
                apiResponse.setCode(SystemStatusCode.SERVICE_UNAVAILABLE.getCode())
                        .setMessage("注册账号失败").setSuccess(false);
        }

        return apiResponse;
    }

    /**
     * 重置密码接口
     *
     * @param user 用户信息
     * @return 返回重置结果
     */
    @ApiOperation("重置密码接口")
    @PostMapping("/resetpassword")
    public ApiResponse<String> resetPassword(@RequestBody UserDTO user) {
        ApiResponse<String> apiResponse = new ApiResponse<>();
        // 判空
        if (user == null || user.getEmail() == null || user.getCaptcha() == null) {
            apiResponse.setSuccess(false).setCode(SystemStatusCode.BAD_REQUEST.getCode()).setMessage("请输入完整信息");
        } else {
            // 获取验证码
            String captcha = stringRedisTemplate.opsForValue().get("mealpickpro:captcha:reset:" + user.getEmail());

            if (captcha != null && captcha.equals(user.getCaptcha())) {
                UpdateWrapper<UserMeal> updateWrapper = new UpdateWrapper<>();
                updateWrapper.eq("email", user.getEmail());
                userMealService.update(new UserMeal().setPassword(SecureUtil.sha256(user.getPassword())), updateWrapper);
                apiResponse.setCode(200).setSuccess(true).setMessage("重置密码成功！");
            } else {
                apiResponse.setCode(500).setSuccess(false).setMessage("验证码错误");
            }
        }
        return apiResponse;
    }
}


